07 datetime日期时间
写代码经常要处理时间——记录日志要时间戳,设置超时要计算时间差,展示给用户要格式化日期。Python的datetime模块就是专门干这个的。
datetime模块提供了几个核心类:date处理日期,time处理时间,datetime处理日期+时间,timedelta处理时间间隔。
一、获取当前时间
1.1 当前日期
python
from datetime import date
today = date.today()
print(today) # 2026-06-13
print(today.year) # 2026
print(today.month) # 6
print(today.day) # 131.2 当前日期时间
python
from datetime import datetime
now = datetime.now()
print(now) # 2026-06-13 10:30:45.123456
print(now.year) # 2026
print(now.month) # 6
print(now.day) # 13
print(now.hour) # 10
print(now.minute) # 30
print(now.second) # 45
print(now.microsecond) # 1234561.3 UTC时间
python
from datetime import datetime, timezone
# UTC时间(世界标准时间)
utc_now = datetime.now(timezone.utc)
print(utc_now) # 2026-06-13 02:30:45.123456+00:00
# 或者用utcnow()(3.12+已弃用,建议用上面的方式)
utc_now = datetime.utcnow()二、创建日期时间
2.1 构造函数
python
from datetime import date, datetime
# 创建日期
d = date(2026, 6, 13)
print(d) # 2026-06-13
# 创建日期时间
dt = datetime(2026, 6, 13, 10, 30, 0)
print(dt) # 2026-06-13 10:30:00
# 可以省略部分参数
dt = datetime(2026, 6, 13) # 时间默认为00:00:002.2 从字符串解析
python
from datetime import datetime
# 从ISO格式解析
dt = datetime.fromisoformat("2026-06-13T10:30:00")
print(dt) # 2026-06-13 10:30:00
# 带时区的ISO格式
dt = datetime.fromisoformat("2026-06-13T10:30:00+08:00")2.3 从时间戳创建
python
from datetime import datetime
# 当前时间戳(秒)
timestamp = datetime.now().timestamp()
print(timestamp) # 1750000000.123456
# 从时间戳创建datetime
dt = datetime.fromtimestamp(timestamp)
print(dt) # 2026-06-13 10:30:00.123456
# 从时间戳创建date
from datetime import date
d = date.fromtimestamp(timestamp)
print(d) # 2026-06-13三、时间间隔:timedelta
3.1 创建时间间隔
python
from datetime import timedelta
# 创建时间间隔
td = timedelta(days=7)
td = timedelta(hours=2, minutes=30)
td = timedelta(weeks=1, days=3)
td = timedelta(days=1, seconds=3600)3.2 时间计算
python
from datetime import datetime, timedelta
now = datetime.now()
# 7天后
future = now + timedelta(days=7)
print(future)
# 3小时前
past = now - timedelta(hours=3)
print(past)
# 1周前
last_week = now - timedelta(weeks=1)
# 计算两个时间的差
diff = future - now
print(diff.days) # 7
print(diff.seconds) # 0
print(diff.total_seconds()) # 604800.03.3 timedelta的属性
python
from datetime import timedelta
td = timedelta(days=7, hours=2, minutes=30, seconds=15)
td.days # 7
td.seconds # 9015 (2*3600 + 30*60 + 15)
td.total_seconds() # 618615.0
# 转换为其他单位
td / timedelta(hours=1) # 170.5(总小时数)
td / timedelta(minutes=1) # 10230.25(总分钟数)四、格式化输出
4.1 strftime()
把日期时间对象格式化为字符串。
python
from datetime import datetime
now = datetime.now()
# 常用格式
now.strftime("%Y-%m-%d") # '2026-06-13'
now.strftime("%Y-%m-%d %H:%M:%S") # '2026-06-13 10:30:45'
now.strftime("%Y年%m月%d日") # '2026年06月13日'
now.strftime("%H:%M") # '10:30'4.2 常用格式码
| 格式码 | 含义 | 示例 |
|---|---|---|
%Y | 四位年份 | 2026 |
%m | 月份(01-12) | 06 |
%d | 日(01-31) | 13 |
%H | 24小时制(00-23) | 10 |
%I | 12小时制(01-12) | 10 |
%M | 分钟(00-59) | 30 |
%S | 秒(00-59) | 45 |
%f | 微秒 | 123456 |
%A | 星期全名 | Friday |
%a | 星期缩写 | Fri |
%B | 月份全名 | June |
%b | 月份缩写 | Jun |
%p | AM/PM | AM |
%j | 年内天数(001-366) | 164 |
%U | 年内周数(周日为起始) | 23 |
%W | 年内周数(周一为起始) | 23 |
%w | 星期几(0=周日) | 5 |
%Z | 时区名 | CST |
%z | UTC偏移 | +0800 |
%% | 字面上的% | % |
4.3 strptime()
把字符串解析为datetime对象。
python
from datetime import datetime
# 解析日期字符串
dt = datetime.strptime("2026-06-13", "%Y-%m-%d")
print(dt) # 2026-06-13 00:00:00
# 解析完整日期时间
dt = datetime.strptime("2026-06-13 10:30:45", "%Y-%m-%d %H:%M:%S")
# 解析中文格式
dt = datetime.strptime("2026年06月13日", "%Y年%m月%d日")4.4 isoformat()
生成ISO 8601格式字符串。
python
from datetime import datetime
now = datetime.now()
now.isoformat() # '2026-06-13T10:30:45.123456'
# 带时区
from datetime import timezone
now_utc = datetime.now(timezone.utc)
now_utc.isoformat() # '2026-06-13T02:30:45.123456+00:00'五、时间戳
5.1 获取时间戳
python
from datetime import datetime
now = datetime.now()
# 转为时间戳(浮点数,秒)
timestamp = now.timestamp()
print(timestamp) # 1750000000.123456
# 整数时间戳
int_timestamp = int(now.timestamp())
print(int_timestamp) # 1750000000
# 毫秒时间戳
ms_timestamp = int(now.timestamp() * 1000)
print(ms_timestamp) # 17500000001235.2 从时间戳创建
python
from datetime import datetime
# 秒级时间戳
dt = datetime.fromtimestamp(1750000000)
# 毫秒时间戳
dt = datetime.fromtimestamp(1750000000123 / 1000)六、星期几
python
from datetime import date
today = date.today()
# weekday():0=周一,6=周日
today.weekday() # 4(周五)
# isoweekday():1=周一,7=周日
today.isoweekday() # 5(周五)
# 获取星期名称
import calendar
calendar.day_name[today.weekday()] # 'Friday'七、实用技巧
7.1 计算年龄
python
from datetime import date
def calculate_age(birthdate):
today = date.today()
age = today.year - birthdate.year
if (today.month, today.day) < (birthdate.month, birthdate.day):
age -= 1
return age
birthday = date(1998, 6, 13)
print(f"年龄: {calculate_age(birthday)}岁")7.2 计算两个日期之间的天数
python
from datetime import date
d1 = date(2026, 1, 1)
d2 = date(2026, 6, 13)
diff = d2 - d1
print(f"相差{diff.days}天") # 相差163天7.3 获取本月第一天和最后一天
python
from datetime import date
import calendar
today = date.today()
# 本月第一天
first_day = today.replace(day=1)
# 本月最后一天
last_day = today.replace(day=calendar.monthrange(today.year, today.month)[1])
print(f"本月: {first_day} ~ {last_day}")7.4 判断是否为工作日
python
from datetime import date
def is_workday(d):
"""判断是否为工作日(周一到周五)"""
return d.weekday() < 5
today = date.today()
print(f"今天{'是' if is_workday(today) else '不是'}工作日")7.5 格式化为相对时间
python
from datetime import datetime, timedelta
def time_ago(dt):
"""格式化为相对时间"""
now = datetime.now()
diff = now - dt
if diff < timedelta(minutes=1):
return "刚刚"
elif diff < timedelta(hours=1):
return f"{diff.seconds // 60}分钟前"
elif diff < timedelta(days=1):
return f"{diff.seconds // 3600}小时前"
elif diff < timedelta(days=30):
return f"{diff.days}天前"
elif diff < timedelta(days=365):
return f"{diff.days // 30}个月前"
else:
return f"{diff.days // 365}年前"
post_time = datetime(2026, 6, 1, 10, 0, 0)
print(time_ago(post_time)) # 12天前7.6 处理时区
python
from datetime import datetime, timezone, timedelta
# 创建带时区的时间
china_tz = timezone(timedelta(hours=8))
now_china = datetime.now(china_tz)
print(now_china) # 2026-06-13 10:30:45+08:00
# 转换时区
utc_tz = timezone.utc
now_utc = now_china.astimezone(utc_tz)
print(now_utc) # 2026-06-13 02:30:45+00:00
# 去掉时区信息
naive = now_china.replace(tzinfo=None)八、与time模块的区别
datetime和time模块都能处理时间,但用途不同:
python
# datetime模块:面向对象,适合日期计算
from datetime import datetime, timedelta
now = datetime.now()
future = now + timedelta(days=7)
# time模块:底层时间操作,适合性能敏感场景
import time
timestamp = time.time() # 获取时间戳
time.sleep(1) # 休眠1秒| 特性 | datetime | time |
|---|---|---|
| 风格 | 面向对象 | 函数式 |
| 日期计算 | 方便 | 不方便 |
| 时间戳 | 需要转换 | 直接支持 |
| 休眠 | 不支持 | sleep() |
| 精度 | 微秒 | 依赖系统 |
一般情况下用datetime就够了。
九、总结
datetime模块的核心类:
| 类 | 用途 |
|---|---|
date | 日期(年月日) |
time | 时间(时分秒微秒) |
datetime | 日期+时间 |
timedelta | 时间间隔 |
timezone | 时区 |
常用操作:
| 操作 | 代码 |
|---|---|
| 获取当前时间 | datetime.now() |
| 获取当前日期 | date.today() |
| 格式化输出 | dt.strftime("%Y-%m-%d") |
| 解析字符串 | datetime.strptime(s, fmt) |
| 时间计算 | dt + timedelta(days=7) |
| 计算差值 | (dt2 - dt1).days |
| 获取时间戳 | dt.timestamp() |
| 从时间戳创建 | datetime.fromtimestamp(ts) |
记住datetime.now()、strftime()、strptime()、timedelta这四个就够应付大部分场景了。